package comp 
{
	use namespace comp_layout;
	
	import comp.Interface.IDispose;
	import comp.style.IStyleManager;
	import comp.style.StyleManager;
	
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Rectangle;
	import flash.utils.describeType;
	import flash.utils.getQualifiedClassName;
	
	import mx.core.Singleton;

	/**
	 * <h1>自定义组件基类</h1>
	 * 1.提供样式功能   getStyle("styleName")是实现所有控件样式的基础。</br>
	 * 2.实现IDispose接口方便销毁对像，释放对象。</br>
	 * 3.initialize()方法，调用此方法之后控件才会显示。
	 * </br>
	 * 示例:comp.ListBase ,comp.Scrollbar,comp.Button,comp.InputText,comp.Panel,comp.Label,comp.Accordion
	 * @author:pu
	 */
	public class UIComponent extends Sprite implements IDispose
	{
		//public
		public function UIComponent()
		{
		}
		
		public function get enabled():Boolean
		{
			return _enabled;
		}
		
		/**
		 * 设置按钮是否可用
		 */
		public function set enabled(value:Boolean):void
		{
			_enabled = value;	
		}
		
		/**
		 * 当前控件的显示区域
		 */
		comp_layout function get wholeRect():Rectangle
		{
			return comp_layout::_wholeRect;
		}
		
		comp_layout function set wholeRect(value:Rectangle):void
		{
			comp_layout::_wholeRect = value;
		}
		
		/**
		 * 控件的最大高度。
		 * 主要用于有滚动条的panel控件，在计算控件大小的时候计算最大高度
		 */
		public function get maxHeight():Number
		{
			return _maxHeight;
		}

		public function set maxHeight(value:Number):void
		{
			_maxHeight = value;
		}

		public override function get height():Number
		{
			return _myHeight;
		}

		public override function set height(value:Number):void
		{
			_myHeight = value;
			this._autoH=false;
		}

		public override function get width():Number
		{
			return _myWidth;
		}

		public override function set width(value:Number):void
		{
			_myWidth = value;
			this._autoW=false;
		}
		
		public function get tag():Object
		{
			return _tag;
		}
		
		/**
		 * 对像标签。
		 * 实现mvc的基础。
		 */
		public function set tag(value:Object):void
		{
			_tag = value;
		}
		
		
		/**
		 * 销毁对像 释放内存资源
		 */
		public function dispose():void
		{
			_style=null;
			_tag=null;
			_golbal=null;
			this.initialized=false;
		}
		
		/**
		 * sprite的宽度
		 */
		public function get spriteWidth():Number
		{
			return super.width;
		}
		
		public function set spriteWidth(value:Number):void
		{
			super.width=value;
		}
		
		/**
		 *  sprite的高度
		 */
		public function get spriteHeight():Number
		{
			return super.height;
		}
		
		public function set spriteHeight(value:Number):void
		{
			super.height=value;
		}
		
		/**
		 *<h1>Component初使化</h1>
		 * 步骤:1首先初使化样式stylesInitialized(),2创建子对像createChildren().3调用子对像创建完成createChildrened()方法,4设定初使化完成.
		 */
		public function initialize():void
		{
			if (initialized)
				return;
			//初使化样式
			stylesInitialized();
			// 创建子对像.
			createChildren();
			createChildrened();
			initialized=true;//初使化完成
		}
		
		/**
		 * 添加子对像</br>
		 * 首先调用addingChild();然后addChild(),最后addedChild()；
		 */
		override public function addChild(child:DisplayObject):DisplayObject
		{
			addingChild(child);
			super.addChild(child);
			addedChild(child);
			return  child;
		}
		
		/**
		 * 添加子对像</br>
		 * 首先调用addingChild();然后addChild(),最后addedChild()；
		 */
		override public function addChildAt(child:DisplayObject, index:int):DisplayObject
		{
			addingChild(child);
			super.addChildAt(child,index);
			addedChild(child);
			return  child;
		}
		
	
		//protected
		/**
		 * 添加子对像前初使化子对像的样式child.stylesInitialized();
		 */
		protected function addingChild(child:DisplayObject):void
		{
			if(child is UIComponent)
			{
				UIComponent(child).initialize();
			}
		}
		
		/**
		 * 子对像添加完成后子对像的初使化initialize();
		 */
		protected function addedChild(child:DisplayObject):void
		{
			if(child is UIComponent)
			{
				
			}
		}
		
		/**
		 * 子对像创建完成</br>
		 * commitStyles();//实现样式
		 * commitProperties();//写入属性
		 * calculateSize();//计算大小
		 * merge();//合并可视化样式，比如
		 */
		protected function createChildrened():void
		{
			commitStyles();//显示样式
			commitProperties();//写入属性			
			calculateSize();//计算大小
			merge();
		}

		/**
		 * 创建子对像
		 */
		protected function createChildren():void
		{
			
		}
		
		/**
		 * 1.签入样式
		 * 当控件子对像创造完成createChildren()后执行这步  
		 */
		protected function commitStyles():void 
		{
			
		}
		
		/**
		 *	2.签入属性
		 *  当控件子对像创造完成createChildren()，样式签入commitStyles()后执行这步  
		 */
		protected function commitProperties():void
		{
			
		}
		
		/**
		 * 3重新计算大小因为当样签入完后大小可能发生改变
		 */ 		
		protected function calculateSize():void
		{
			
		}
		
		/**
		 * 3.布局，合并显示.实现可视化的效果 比如背景，皮肤等
		 */
		protected function merge():void
		{
			
		}
		
		//*********************** 样式 ********************************
		/**
		 * 初使化样式 
		 * 1className中得样式优先.
		 * 2模板中得样式
		 */
		public function stylesInitialized():void
		{
			if (!_overrides)
				_overrides = {};
			
			var theme:*=this.styleManger.getStyle(_themeName);//主题
			if(this.getStyle("useTheme") && theme)
				copyStyle(theme,this);
			
			var cls:*=this.styleManger.getStyle(this.className);
			if(cls)//样式类名
				copyStyle(cls,this);//设置样式表样式
			
			if(this._style)//样式表
				copyStyle(_style,this);
			
			_golbal=styleManger.getStyle("Global");//设置默认全局样式	
		
		}
		
		public function get className():String
		{
			return _className;
		}
		/**
		 * 类名
		 */
		public function set className(value:String):void
		{
			_className = value;
		}
		
		/**
		 * 样式表
		 */
		public function get style():Object
		{
			return _style;
		}
		/**
		 * 样式对像必须是这种格式{"styleName":value,"styleName1":value1}
		 * 如果设置了持属性不能实现主题样式
		 */
		public function set style(value:Object):void
		{
			_style=value;
		}

		/**
		 * 样式改变的时候调用</br>
		 * 
		 */
		public function styleChanged(styleProp:String,newValue:*):void
		{
			if(styleProp=="width" && this.width==0)
				this.width=newValue;
			else if(styleProp=="height" && this.height==0)
				this.height=newValue;
			else if(styleProp=="merge")
				this.merge()
		}
		
		/**
		 * 清除样式
		 */
		public function clearStyle(styleProp:String):void
		{
			setStyle(styleProp,undefined);
		}
		
		/**
		 * 得到样式</br>
		 * 1首先从_overrides重写的样式中查找，2如未找到在从_style样式表中查找,3如还未找到在从UIComponent中查找,
		 * 如果还未找到返回undefined.
		 */
		public	function getStyle(styleProp:String):* 
		{
			var v:*;
			
			//自身的属性是最优先的，所以先从自己找
			if (styleProp in this) 
			{
				v = this[styleProp];
				if (v) //如果有值 不为NaN ,null,undefined,0,""
					return v;
			}
			
			//重写的样式表中找
			if(_overrides)
			{
				if (styleProp in _overrides)
				{
					v = _overrides[styleProp];//如果有值 不为NaN ,null,undefined,0,""
					if (v!== undefined)
						return v;
				}
			}	
			
			if (_golbal)//全局样式
			{
				if (styleProp in _golbal && _golbal[styleProp]!==undefined)
					return _golbal[styleProp];
			}
			
			if(v==0)
				return v;
			
			if(v!=null && v.toString()=="NaN")
				return 0;
			
			return undefined
		}
		
		/**
		 * 如果样式不可用就返回默认值
		 */
		public function getStyleDefault(styleProp:String,defaultValue:*):*
		{
			var r:*=getStyle(styleProp);
			
			if(r)
				return r;
			else
				return defaultValue;
		}
		/**
		 * 设置样式</br>
		 * 直接写入_overrides重写的样式列表,如果样式属性改变会调用styleChanged()方法
		 */
		public function setStyle(styleProp:String, newValue:*):void
		{
			var oldValue:* = getStyle(styleProp);
			var valueChanged:Boolean = oldValue != newValue;

			if (newValue === undefined) // 
			{
				if (newValue != oldValue)
				{
					_overrides[styleProp] = newValue;
					return;
				}
			}

			_overrides[styleProp] = newValue;
			
			if (valueChanged)
				styleChanged(styleProp,newValue);
	
		}
		
		/**
		 * 返回初使化状态true以完成，flase未完成
		 */
		public function get initialized():Boolean
		{
			return _initialized;
		}
		/**
		 * 设置初使化完成
		 */
		public function set initialized(value:Boolean):void
		{
			_initialized=value;
		}
		
		/**
		 * 是否使用主题功能
		 */
		public function get useTheme():Boolean
		{
			return _useTheme;
		}
		
		/**
		 * @private
		 */
		public function set useTheme(value:Boolean):void
		{
			_useTheme = value;
		}
		
		/**
		 *  主题模板名
		 */
		public function get themeName():String
		{
			return _themeName;
		}
		
		/**
		 * @private
		 */
		public function set themeName(value:String):void
		{
			_themeName = value;
		}
		
		/**
		 * 得到样式管理类接口
		 */
		public function get styleManger():IStyleManager
		{
			if(!_styleManger)
			{
				if(!Singleton.getClass("comp.style.IStyleManager"))
					Singleton.registerClass("comp.style.IStyleManager",comp.style.StyleManager);
				_styleManger=Singleton.getInstance("comp.style.IStyleManager") as IStyleManager;
			}
			return _styleManger;
		}
		
		protected var _style:Object;//原始的样式
		protected var _overrides:Object;//重写的样式
		protected var _maxHeight:Number=0;//最大高度
		protected var _golbal:Object={};//全局样式
		protected var _enabled:Boolean=true;//是否可用true可用
		//private
		private var _tag:Object;//标签
		
		//样式
		comp_layout var _wholeRect:Rectangle;//整个区域
		comp_layout var _myWidth:Number=0;//宽
		comp_layout var _myHeight:Number=0;//高
		comp_layout var _autoH:Boolean=true;
		comp_layout var _autoW:Boolean=true;
		comp_layout var _initialized:Boolean = false;//初使化
		private var _className:String;//样式名
		private var _useTheme:Boolean=true;//是否可以使用模板
		protected var _themeName:String;//模板名
		private static var _styleManger:IStyleManager;//样式管理类实现全局样式和模板管理
		/**
		 * copy样式
		 */
		public static function copyStyle(style:*,ui:UIComponent):void
		{
			var s:XML=describeType(style);
			var v:*;
			if(s.@isDynamic=="true")
			{
				for(var i:* in style)
				{
					try{
						v=style[i];
						if(v || v==undefined)
							ui.setStyle(i,v);
					}catch(e:*){trace(e);}//end try
				}//end for
			}
			else
			{
				var pre:String=s..accessor.@name.toXMLString();
				var arr:Array=pre.split('\n');
				var p:String;
				for(var n:String in arr)
				{
					p=arr[n];
					try{
						v=style[p];
						if(v || v==undefined)
							ui.setStyle(p,v);
					}catch(e:*){trace(e);}//end try
				}//end for
			}//end if isDynamic
		}
										  
	}
}